﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.Net;
using System.Threading;

public class SocketClient
{
    private Socket socket;
    private string ip;
    private int port;

    //private ManualResetEvent sendDone = new ManualResetEvent(false);
    //private ManualResetEvent receiveDone = new ManualResetEvent(false);

    public SocketClient(string ip, int port)
    {
        this.ip = ip;
        this.port = port;
        connect();

        receive();
        //receiveDone.WaitOne();
    }

    private void connect()
    {
        IPAddress ipAddress = IPAddress.Parse(ip);
        socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        socket.Connect(ipAddress, port);
    }

    public void Command(string command)
    {
        Command(command, string.Empty);
    }

    public void Command(string command, string data)
    {
        if (!socket.Connected)
            connect();

        send(string.Format("{0} {1}\r\n", command, data));
    }

    private void send(string data)
    {
        byte[] byteData = Encoding.ASCII.GetBytes(data);
        socket.Send(byteData);
        //socket.BeginSend(byteData, 0, byteData.Length, 0, new AsyncCallback(SendCallback), socket);
    }


    private void receive()
    {
        Thread newThread = new Thread(receiveCore);
        newThread.Start();
    }

    private string receiveCache = string.Empty;

    private void receiveCore()
    {
        while (true)
        {

            try
            {
                //创建一个字节数组接收数据
                byte[] arrMsgRec = new byte[1024 * 1024 * 2];
                //接收数据
                int length = socket.Receive(arrMsgRec);
                //将字节数组转换成字符串,此时是将所有的元素都转成字符串了，而真正接收到的只有服务端发来的几个字符。
                receiveCache += System.Text.Encoding.UTF8.GetString(arrMsgRec, 0, length);

                dealReciveData();

            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
                //结束当前线程
                //Thread.CurrentThread.Abort();
            }
        }
    }

    private void dealReciveData()
    {
        var result = receiveCache.IndexOf("\r\n");
        while (result != -1)
        {
            string text = receiveCache.Substring(0, result);
            receiveCache = receiveCache.Substring(result + 2, receiveCache.Length - result - 2);
            dealCommand(text);

            result = receiveCache.IndexOf("\r\n");
        }
    }

    private void dealCommand(string text)
    {
        var result = text.IndexOf(' ');
        if (result != -1)
        {
            var key = text.Substring(0, result);
            var data = text.Substring(result + 1, text.Length - result - 1);

            if (commandList.ContainsKey(key))
            {
                commandList[key](data);
                return;
            }
        }

        if (UnkownCommandHandler != null)
            UnkownCommandHandler(text);
    }



    public void Close()
    {
        if (socket.Connected)
            socket.Shutdown(SocketShutdown.Both);
    }

    public event CommandHandler UnkownCommandHandler;

    private Dictionary<string, CommandHandler> commandList = new Dictionary<string, CommandHandler>();
    public void AddCommand(string key, CommandHandler handler)
    {
        if (commandList.ContainsKey(key))
            commandList[key] = handler;
        else
            commandList.Add(key, handler);
    }

    public void RemoveCommand(string key)
    {
        if (commandList.ContainsKey(key))
            commandList.Remove(key);
    }
}

public delegate void CommandHandler(string data);

